package com.xzy.sms.web.system.controller;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.google.common.collect.Maps;
import com.xzy.sms.web.system.service.security.UserProfile;
import com.xzyframework.utils.ResourceUtil;

/**
 * @desc 登录控制器
 * @author WuJiangWu
 * @date 2018年7月15日
 */
@Controller
public class CommonController {
    
    /** FIXME */
    private static final Logger LOG = LoggerFactory.getLogger(CommonController.class);
    
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String login() {
        return "index";
    }
    
    /**
     * 登录页面请求
     * @param request request
     * @param response response
     * @param model model
     * @return 路径
     */
    @RequestMapping(value = "/login", method = RequestMethod.GET, headers = "X-Requested-With=XMLHttpRequest")
    @ResponseStatus(HttpStatus.FORBIDDEN)
    @ResponseBody
    public Map<String, String> ajaxLogin(HttpServletRequest request, HttpServletResponse response, Model model) {
        String kickout = request.getParameter("kickout");
        Map<String, String> map = Maps.newHashMap();
        if ("1".equals(kickout)) {
            map.put("code", "kickoutSessionTimeout");
        } else {
            map.put("code", "sessionTimeout");
        }
        map.put("message", "会话过期，请重新登录");
        return map;
    }
    
    /**
     * 登录页面请求
     * @param request request
     * @param response response
     * @param model model
     * @return 路径
     */
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String login(HttpServletRequest request, HttpServletResponse response, Model model) {
        // 如果已经登录，则跳转到管理首页
        if (getCurrentAccount() != null) {
            return "redirect:/";
        }
        model.addAttribute("systemProfilesTitle", ResourceUtil.getConfigByName("title"));
        return "login/login";
    }
    
    /**
     * 提交登录
     * @param username xx
     * @param password xx
     * @return 路径
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login(@RequestParam("username") String username, @RequestParam("password") String password, ModelMap modelMap) {
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
        	subject.login(token);//授权认证
        	return "redirect:/";
		} catch (UnknownAccountException e) {//账户不存在或锁定
			modelMap.put("msg", e.getMessage());
            LOG.error("登录失败", e.getMessage());
    	} catch (IncorrectCredentialsException  e) {//密码格式不正确
    		modelMap.put("msg", "用户名或密码不正确");
            LOG.error("登录失败", "用户名或密码不正确");
		}catch (AuthenticationException e) {
			modelMap.put("msg", "登录失败");
            LOG.error("登录失败", "登录失败");
		}
        return "login/login";
    }
    
    /**
     * 登出请求
     * @param request request
     * @param response response
     * @param model model
     * @return 路径
     */
    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public String logout(HttpServletRequest request, HttpServletResponse response, Model model) {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return "login/logout";
    }
    
    /**
     * 500跳转
     * @param model Model
     * @param request req
     * @return String
     */
    @RequestMapping(value = "/error/error500", headers = "X-Requested-With=XMLHttpRequest")
    @ResponseBody
    public Map<String, String> error500Ajax(Model model, HttpServletRequest request) {
        Map<String, String> map = Maps.newHashMap();
        map.put("code", "error500");
        map.put("message", "系统发生内部错误");
        return map;
    }
    
    /**
     * 500跳转
     * @param model Model
     * @param request req
     * @return String
     */
    @RequestMapping(value = "/error/error500")
    public String error500(Model model, HttpServletRequest request) {
        try {
            Exception ex = (Exception) request.getAttribute("exceptionData");
            if (ex != null) {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                // 把错误堆栈储存到流中
                ex.printStackTrace(new PrintStream(bos));
                String exceptionData = bos.toString();
                exceptionData.replace("\n", "<br/>");
                model.addAttribute("exceptionData", exceptionData);
            }
        } catch (Exception e) {
            // 防止异常中出现异常
        }
        return "error/error500";
    }
    
    /**
     * 取出Shiro中的当前用户Id.
     * @return xx
     */
    private String getCurrentAccount() {
        UserProfile user = (UserProfile) SecurityUtils.getSubject().getPrincipal();
        if (null != user) {
            return user.getUserName();
        }
        return null;
    }
}
